import React, { useCallback, useState } from "react";

interface ChildProps {
    onSave: () => void;
  }

  // 子组件,使用 React.memo 进行优化,只有当 onSave 变化时才会重新渲染
const CallbackChild: React.FC<ChildProps> = React.memo(({ onSave }) => {
    console.log("Child 组件渲染"); // 用于观察渲染次数
    return(
        <>
        <div>
            <strong>React.memo </strong>
            <ul>
                <li>React.memo 是一个高阶组件,用于优化组件的性能。</li>
                <li>优化子组件: React.memo 会浅比较子组件的 props,如果 props 没有变化,则阻止子组件重新渲染。</li>
            </ul>
        </div>
        <div>
            <strong>未使用 useCallback 的问题</strong>
            <ul>
                <li>如果直接定义 handleSave 函数 <pre>（如 const handleSave = () = {}）</pre>,</li>
                <li>每次父组件渲染时都会创建新的函数引用,即使 count 没有变化,子组件的 onSave prop 引用也会变化,导致 React.memo 失效,子组件被迫重新渲染</li>
            </ul>
        </div>
        <div>
            <strong>使用 useCallback 缓存函数</strong>
            <ul>
                <li>useCallback 会返回一个记忆化的函数,只有当依赖项（这里是 count）变化时才会重新创建</li>
                <li>当 count 不变时,handleSave 的引用保持不变,子组件不会重新渲染</li>
            </ul>
           </div>
       
       <div>
        <strong>何时使用 useCallback</strong>
        <ul>
            <li>当函数作为 prop 传递给子组件,且子组件使用 React.memo 或 shouldComponentUpdate 进行优化时。</li>
            <li>当函数被用作依赖项（如在 useEffect 的依赖数组中）。</li>
        </ul>
       </div>
        <div>
             <button onClick={onSave}>保存</button>;
        </div>
        </>
    );
  });
  
  // 父组件
  const CallbackParent = () => {
    const [count, setCount] = useState(0);
  
    // 使用 useCallback 缓存函数
    const handleSave = useCallback(() => {
      console.log("保存数据:", count);
      // 这里可以执行保存逻辑
    }, [count]); // 只有 count 变化时才重新创建函数
  
    return (
      <div>
        <p>Count: {count}</p>
        <button onClick={() => setCount(count + 1)}>增加</button>
        <CallbackChild onSave={handleSave} />
      </div>
    );
  };

  export default CallbackParent;